Title Banner


Technotes


Constructing a Business Card DSSpec



Technote AO 02September 1994



Written by: Scott Kuechle September 1994

This Technical Note describes how to create an AOCE catalog services specification structure (DSSpec) for an AOCE business card catalog item, given just a file system specification record (FSSpec) for the item.


Introduction

The AOCE catalog services specification structure, defined by the DSSpec data type (see Inside Macintosh :AOCE Application Interfaces 2-36), is used throughout AOCE for performing various tasks such as getting and setting attributes in a record, specifying message addresses, etc. Many of the AOCE software routines defined in Inside Macintosh :AOCE Application Interfaces will give you a DSSpec for a given catalog item. For example, the Standard Catalog package contains a Catalog-Browsing panel, which allows the user to select records in catalogs. Once a selection is made, the selected item is returned as a DSSpec structure.

However, there are instances where you will be given just an FSSpec for a catalog item, and you will need to construct a DSSpec structure for that same item. For example, if your application uses the Drag Manager to handle dragging HFS objects onto your application's windows, it's possible that you will receive a drag of an HFS object that represents an AOCE catalog item (like a business card). In this case, all you are given for the object is an FSSpec structure. If you wanted to use some of the routines defined in the AOCE Catalog Manager on that item, you would need to pass a RecordID or DSSpec structure describing that item.
Building a DSSpec

The following describes how to construct a DSSpec (from just a FSSpec) for a business card. Basically, business cards are degenerate personal catalogs containing a distinguished record. To find the distinguished record, we look for a pseudonym with a known type. By enumerating that pseudonym you can find the distinguished record. The process is as follows:

* Open the business card with DirOpenPersonalDirectory to get the reference number.

* Use DirEnumerateGet to get the distinguished record's CID (the CID and reference number are enough to access the record).

To make a fully specified packedDSSpec:

* Call DirGetNameAndType passing the CID gotten above, to get the distinguished record's type (use the file name as the record's name. If it is not the same, it is OK to set the record's name to the file name).

* Call DirMakePersonalDirectoryRLI, using the business card reference number to get the RLI.

* Create the packedDSSpec using the OCEPackedDSSpecSize and OCEPackedDSSpec routines.

Code Example

Here is the code, written in MPW C. You call the ConstructPackedDSSpec routine, passing a valid FSSpec along with a pointer to an empty PackedDSSpecPtr type variable. The code then returns a pointer to a valid PackedDSSpec structure in the packedDSSpecPtr parameter:

/* global data */

#define kEnumBufferSize (4096) /* Working data buffer */

/*****************************************************************

* ConstructPackedDSSpec

*

* main code that builds a packedDSSpec struct from an FSSpec

* for a Business Card.

*****************************************************************/

OSErr ConstructPackedDSSpec( FSSpecPtr fsspecPtr,

PackedDSSpecPtr *packedDSSpecPtr )

{

OSErr err;

unsigned short packedSpecSize;

DSSpec dsspec;

RecordID rid;

RString name,type;

PackedRLI packedRLI;

LocalRecordID localRID;

CreationID cid;

name.dataLength = kRStringMaxBytes;

type.dataLength = kRStringMaxBytes;

OCENewLocalRecordID(&name,&type,&cid,&localRID);

OCENewRecordID(&packedRLI,&localRID,&rid);

err = GetRecordID(fsspecPtr,

&rid,

OCEGetIndRecordType(kBusinessCardRecTypeNum));

if (err == noErr)

{

dsspec.extensionType = kOCEentnDSSpec;

dsspec.extensionSize = 0;

dsspec.extensionValue = NULL;

dsspec.entitySpecifier = &rid;

packedSpecSize = OCEPackedDSSpecSize(&dsspec);

*packedDSSpecPtr = (PackedDSSpecPtr)NewPtr(packedSpecSize);

err = MemError();

if (err == noErr)

{

err = OCEPackDSSpec(&dsspec, *packedDSSpecPtr, packedSpecSize);

}

}

return (err);

}

/*****************************************************************

* GetRecordID

*

*

*****************************************************************/

OSErr GetRecordID( FSSpecPtr fsspec,

RecordIDPtr ridPtr,

RStringPtr recordType)

{

OSErr err;

DirParamBlock pb;

pb.openPersonalDirectoryPB.fsSpec = fsspec;

pb.openPersonalDirectoryPB.accessRequested = fsRdPerm;

/* get reference number for Business Card */

err = DirOpenPersonalDirectory(&pb);

if (err == noErr)

{

err = DoEnumerateGet( pb.openPersonalDirectoryPB.dsRefNum,

(long)&ridPtr->local,

recordType);

if (err == noErr)

{

pb.getNameAndTypePB.identity = 0;

pb.getNameAndTypePB.aRecord = ridPtr;

err = DirGetNameAndType (&pb, false);

if (err == noErr)

{

pb.makePersonalDirectoryRLIPB.fromFSSpec = fsspec;

pb.makePersonalDirectoryRLIPB.pRLIBufferSize = kRLIMaxBytes;

pb.makePersonalDirectoryRLIPB.pRLI = ridPtr->rli;

err = DirMakePersonalDirectoryRLI(&pb);

}

}

DirClosePersonalDirectory(&pb);

}

return (err);

}

/*****************************************************************

* DoEnumerateGet

*

*

*****************************************************************/

OSErr DoEnumerateGet(short dsRefNum,

long clientData,

RStringPtr recordType)

{

OSErr err;

RStringPtr typeList[1];

DirParamBlock dirParamBlock;

Ptr buffer;

#define GET (dirParamBlock.enumerateGetPB)

#define PARSE (dirParamBlock.enumerateParsePB)

buffer = NewPtr(kEnumBufferSize);

if (buffer == NULL)

err = MemError();

else

{

GET.dsRefNum = dsRefNum;

GET.identity = 0;

GET.aRLI = NULL; /* ignored if non-zero dsRefNum is passed */

GET.startingPoint = 0;

GET.sortBy = kSortByType;

GET.sortDirection = kSortForwards;

typeList[0] = recordType;

GET.typesList = &typeList;

GET.typeCount = 1;

GET.enumFlags = kEnumPseudonymMask;

GET.includeStartingPoint = true;

GET.matchNameHow = kMatchAll;

GET.matchTypeHow = kExactMatch;

GET.getBuffer = buffer;

GET.getBufferSize = kEnumBufferSize;

err = DirEnumerateGet (&dirParamBlock, false);

if (err == noErr || err == kOCEMoreData)

{

PARSE.clientData = clientData;

PARSE.eachEnumSpec = myForEachDirEnumSpec;

err = DirEnumerateParse (&dirParamBlock, false);

}

}

return (err);

#undef GET

#undef PARSE

}

/*****************************************************************

* myForEachDirEnumSpec

*

*

*****************************************************************/

static pascal Boolean myForEachDirEnumSpec (long clientData,

const DirEnumSpec *enumSpec)

{

OSErr err;

if ((enumSpec->enumFlag & kEnumPseudonymMask))

{

err = OCECopyLocalRecordID(&enumSpec->u.recordIdentifier,

(LocalRecordIDPtr)clientData);

return (true); /* stop, we found it */

}

else

return (false); /* get next one */

}


Further Reference:

* Inside Macintosh :AOCE Application Interfaces

* Inside Macintosh :Files

* Drag Manager Programmer's Guide


Tech Support
Technotes
Previous Technote | Contents | Next Technote


Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help